package com.moyuwanjia.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @author 摸鱼丸加~
 * @create 2022-07-08 12:50
 * 定义该类为一个JDBC的专属配置类，将其导入SpringConfiguration主配置类
 * 此时当前类被导入时，就不需要再使用@Configuration注解来修饰了
 */
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 用于创建一个queryRunner对象，并且传入参数,该参数由spring去查找所管理的
     * 容器中是否有可用的bean存在
     * 问题1：此时创建的对象默认是单例的，但是在之前的模块中有提到，如果使用单例的对象模式，会导致Dao中的方法有的还在使用runner
     *      而有的已经结束了，所以可能会导致线程干扰问题，造成线程不安全，所以就要保证每次创建的实例都是新的，互不干扰
     * 解决：使用Scope注解来控制对象作用范围，使其提供的实例为多例对象
     * 问题2：如果存在多个数据源时，在runner方法中的参数就无法通过类型去匹配了，所以此时
     *       必须由我们手动指定当前使用的数据源
     * 解决：使用@Qualifier注解指定要使用的数据源对象
     *
     * @param dataSource
     * @return runner对象
     */
    @Bean(name = {"queryRunner"})
    @Scope(scopeName = "prototype")
    public QueryRunner createQueryRunner(@Qualifier("dataSource1") DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     * @throws PropertyVetoException
     */
    @Bean(value = {"dataSource1"})
    public DataSource createDataSource1() throws PropertyVetoException {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        comboPooledDataSource.setDriverClass(driver);
        comboPooledDataSource.setJdbcUrl(url);
        comboPooledDataSource.setUser(username);
        comboPooledDataSource.setPassword(password);
        return comboPooledDataSource;
    }


}
